import ast
import operator as op
from rule.设计值解析器 import DesignValueParser  # 确保导入路径正确


class SafeMathEvaluator:
    """
    安全的数学表达式评估器
    """
    def __init__(self):
        self._allowed_operators = {
            ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, 
            ast.Div: op.truediv, ast.Pow: op.pow, ast.USub: op.neg
        }
    
    def eval_expression(self, expr, variables):
        """安全地评估数学表达式"""
        try:
            node = ast.parse(expr, mode='eval').body
            return self._eval(node, variables)
        except Exception as e:
            raise ValueError(f"公式解析错误: {expr}, 错误: {e}")
    
    def _eval(self, node, variables):
        if isinstance(node, ast.Num):  # 数字
            return node.n
        elif isinstance(node, ast.Name):  # 变量
            if node.id in variables:
                return variables[node.id]
            else:
                raise ValueError(f"未定义的变量: {node.id}")
        elif isinstance(node, ast.BinOp):  # 二元运算
            left = self._eval(node.left, variables)
            right = self._eval(node.right, variables)
            return self._allowed_operators[type(node.op)](left, right)
        elif isinstance(node, ast.UnaryOp):  # 一元运算
            operand = self._eval(node.operand, variables)
            return self._allowed_operators[type(node.op)](operand)
        else:
            raise TypeError(f"不支持的表达式类型: {type(node)}")


class RuleCalculator:
    """
    规则计算引擎
    根据终检值和规则计算工序检值
    """
    
    def __init__(self):
        self.evaluator = SafeMathEvaluator()
        self.parser = DesignValueParser()
    
    def calculate_process_value(self, new_final_value: str, rule_type: str, rule_formula: str) -> str:
        """
        根据新终检值和历史规则，计算新的工序检值
        
        Args:
            new_final_value: 新图纸的终检值
            rule_type: 规则类型
            rule_formula: 规则公式
            
        Returns:
            计算出的新工序检值
        """
        if rule_type == "双一致":
            return new_final_value

        elif rule_type == "数值收敛":
            return self._calculate_numeric_convergence(new_final_value, rule_formula)

        elif rule_type in ["过程保障", "语义收敛", "合并双一致"]:
            return new_final_value

        else:
            print(f"未知规则类型: {rule_type}")
            return None
    
    def _calculate_numeric_convergence(self, new_final_value: str, rule_formula: str) -> str:
        """计算数值收敛规则"""
        # 使用解析器解析新终检值
        parsed_value = self.parser.parse(new_final_value)
        
        if parsed_value['type'] == 'unknown':
            print(f"无法解析终检值: {new_final_value}")
            return None
        
        # 准备变量上下文
        variables = {
            'x_lower': parsed_value['lower'] or 0,
            'x_upper': parsed_value['upper'] or 0,
            'x_base': parsed_value['base'] or 0,
            'x': parsed_value['base'] or 0
        }
        
        # 动态执行公式
        try:
            if '=' in rule_formula:
                calc_part = rule_formula.split('=')[1].strip()
                
                if calc_part.startswith('['):
                    # 处理列表表达式
                    return self._process_list_expression(calc_part, variables, parsed_value)
                else:
                    # 处理简单表达式
                    result = self.evaluator.eval_expression(calc_part, variables)
                    return self._format_result(result, parsed_value)
                    
        except Exception as e:
            print(f"公式计算失败: {rule_formula}, 错误: {e}")
            return None
    
    def _process_list_expression(self, calc_part: str, variables: dict, parsed_value: dict) -> str:
        """处理列表表达式 [y_lower, y_upper] = [x_lower + 0.1, x_upper]"""
        calc_part = calc_part[1:-1].strip()
        parts = [part.strip() for part in calc_part.split(',')]
        
        if len(parts) == 2:
            y_lower = self.evaluator.eval_expression(parts[0], variables)
            y_upper = self.evaluator.eval_expression(parts[1], variables)
            
            # 根据原始值的类型决定输出格式
            return self._format_range_result(y_lower, y_upper, parsed_value)
        else:
            raise ValueError("列表表达式必须包含两个部分")
    
    def _format_range_result(self, y_lower: float, y_upper: float, parsed_value: dict) -> str:
        """格式化范围结果"""
        if parsed_value['type'] == 'range':
            return f"{y_lower:.1f}~{y_upper:.1f}"
        elif parsed_value['type'] == 'symmetric_tolerance':
            base = (y_lower + y_upper) / 2
            tolerance = (y_upper - y_lower) / 2
            # 使用g格式化选项智能选择精度
            return f"{base:#g}±{tolerance:#g}"
        elif parsed_value['type'] == 'tolerance':
            base = (y_lower + y_upper) / 2
            tol_lower = y_lower - base
            tol_upper = y_upper - base
            return f"{base:.1f}({tol_lower:.1f},{tol_upper:+.1f})"
        else:
            return f"{y_lower:.1f}~{y_upper:.1f}"
    
    def _format_result(self, result: float, parsed_value: dict) -> str:
        """格式化单值结果"""
        if parsed_value['type'] in ['single_with_symbol', 'simple_single']:
            symbol = parsed_value.get('symbol', '')
            return f"{symbol}{result:.2f}"
        else:
            return f"{result:.2f}"



def test_rule_calculator():
    """测试规则计算引擎（补充正则显示）"""
    calculator = RuleCalculator()
    parser = DesignValueParser()  # 初始化解析器，用于获取正则信息
    
    test_cases = [
        # 原有测试用例
        ("35.6~36.0", "数值收敛", "[y_lower, y_upper] = [x_lower + 0.1, x_upper]"),
        ("48.9(0,+0.4)", "数值收敛", "[y_lower, y_upper] = [x_upper + 0.7, x_lower + 1.5]"),
        ("80810±800", "数值收敛", "[y_lower, y_upper] = [x_lower * 4.49, x_upper * 4.57]"),
        ("427.4~428.2", "双一致", "y = x"),
        ("≤0.3", "数值收敛", "y = x + 0.25"),
        
        # 您提供的完整测试用例
        ("48.9(0,+0.4)", "数值收敛", "[y_lower, y_upper] = [x_upper + 0.7, x_lower + 1.5]"),
        ("1.9～2.8", "数值收敛", "[y_lower, y_upper] = [x_lower + 0.4, x_upper + 0.3]"),
        ("48(0,+0.2)", "数值收敛", "[y_lower, y_upper] = [x_upper - 0.2, x_upper]"),
        ("80810±800", "数值收敛", "[y_lower, y_upper] = [x_lower * 4.49, x_upper * 4.57]"),
        ("17842±120", "数值收敛", "[y_lower, y_upper] = [x_lower - 111, x_upper + 111]"),
        ("≤1.5", "数值收敛", "y = x + 1.17"),
        
        # 新增测试用例
        ("不小于51", "数值收敛", "y = x_lower + 1.7"),
        ("不小于50.5", "数值收敛", "y = x_lower + 1.2"),
        ("48.3(0,+0.2)", "数值收敛", "[y_lower, y_upper] = [x_upper + 0.1, x_upper + 0.3]"),
        ("48±0.2", "数值收敛", "[y_lower, y_upper] = [x_lower + 0.2, x_upper]"),  # 测试对称公差输入但计算结果不对称
    ]
    
    print("规则计算引擎测试结果:")
    print("=" * 80)
    
    for i, (new_final, rule_type, formula) in enumerate(test_cases, 1):
        # 1. 计算工序值
        process_result = calculator.calculate_process_value(new_final, rule_type, formula)
        
        # 2. 解析终检值，获取正则匹配信息
        parsed_final = parser.parse(new_final)
        
        # 3. 单独保存所有输出变量
        case_num = i
        input_final_val = new_final
        rule_type_val = rule_type
        formula_val = formula
        output_process_val = process_result
        # 正则相关变量
        matched_pattern_val = parsed_final.get('matched_pattern', '')
        pattern_desc_val = parsed_final.get('pattern_description', '')
        final_type_val = parsed_final.get('type', 'unknown')
        final_range_val = f"[{parsed_final['lower']} ~ {parsed_final['upper']}]"

        # 4. 打印（补充正则信息）
        print(f"测试用例 {case_num:2d}:")
        print(f"  输入终检值: {input_final_val:15} | 终检值类型: {final_type_val:20} | 匹配正则: {matched_pattern_val:5}")
        print(f"  正则描述: {pattern_desc_val}")
        print(f"  终检值范围: {final_range_val} | 规则类型: {rule_type_val}")
        print(f"  计算公式: {formula_val}")
        print(f"  输出工序值: {output_process_val}")
        print("-" * 80)


if __name__ == "__main__":
    # test_parser()
    print("\n" + "="*100 + "\n")
    test_rule_calculator()